#ifndef ADDIN_H_076A0C36_23B5_4BF6_B51B_DF624F49B364
#define ADDIN_H_076A0C36_23B5_4BF6_B51B_DF624F49B364
/**
 * \file AddIn.h
 *
 * \brief Header file for class CAddIn
 *
 * $Id: AddIn.h,v 1.1.1.1 2008/04/23 13:29:14 mgh Exp $
 *
 *
 * Copyright (C) 2006 Michael G. Herstine <sp1ff@pobox.com>
 *
 * Permission to use, copy, or modify this source code is hereby granted
 * free of  charge, provided  that this copyright  notice appear  on all
 * copies  and  on   all  source  code  derived  from   this  code.   No
 * representation is made regarding the suitability of this software for
 * any  purpose.  It  is provided  "as  is" without  express or  implied
 * warranty.
 *
 *
 * This  file  defines class  CAddIn--  the  one  & only  COM  component
 * exported from this AddIn.
 *
 *
 */

#ifndef STDAFX_H_10C3F2AB_C971_462D_AE43_8D659E613A34
# error "#include 'stdafx.h' before this file for PCH!"
#endif // not "stdafx.h"

#ifndef RESOURCE_H_INCLUDED
# include "resource.h"          // Resource definitions
#endif // not "resource.h"

#ifndef SAMPLECAI_H_INCLUDED
# include "SampleCAI.h"         // MIDL-generated COM bindings
#endif // not "SampleCAI.h"

/**
 * \class CAddIn
 *
 * \brief Incarnates the SampleCAI.CoAddIn COM Component
 *
 *
 * This class backs the one & only COM component exported by this
 * server.
 *
 *
 */

class ATL_NO_VTABLE CAddIn :
  public CComObjectRootEx<CComSingleThreadModel>,
  public CComCoClass<CAddIn, &CLSID_CoAddIn>,
  public ISupportErrorInfo
{
public:
  /// ATL requires a default ctor
  CAddIn();
  /// ATL-defined initialization routine
  HRESULT FinalConstruct();
  /// ATL-defined cleanup routine
  void FinalRelease();

# ifndef DOXYGEN_INVOKED        // Shield the macros from doxygen...
  /// Tell ATL about our Registrar scripts
  DECLARE_REGISTRY_RESOURCEID(IDR_ADDIN)
  /// For GetControllingUnknown
  DECLARE_GET_CONTROLLING_UNKNOWN()
  /// Tell ATL which interfaces we support
  BEGIN_COM_MAP(CAddIn)
    COM_INTERFACE_ENTRY(ISupportErrorInfo)
    COM_INTERFACE_ENTRY_AGGREGATE(IID_IDSAddIn, m_pDSAddIn)
    COM_INTERFACE_ENTRY_AGGREGATE(EnvDTE::IID_IDTCommandTarget, m_pDTEAddIn)
    COM_INTERFACE_ENTRY_AGGREGATE(AddInDO::IID__IDTExtensibility2,
                                  m_pDTEAddIn)
    COM_INTERFACE_ENTRY_AGGREGATE(IID_IDispatch, m_pDTEAddIn)
  END_COM_MAP()
  /// Guard our reference count against child creation side-effects
  DECLARE_PROTECT_FINAL_CONSTRUCT()
# endif // not DOXYGEN_INVOKED

  //////////////////////////////////////////////////////////////////////
  // Interface ISupportsErrorInfo
public:
  STDMETHOD(InterfaceSupportsErrorInfo)(/*[in]*/ REFIID riid);

public:
  /// Display our configuration dialog
  void Configure();
  /// Carry out our command
  void SayHello();

private:
  /// Reference on our aggregated instance of CoDSAddIn
  CComPtr<IUnknown> m_pDSAddIn;
  /// Reference on our aggregated instance of CDTEAddIn
  CComPtr<IUnknown> m_pDTEAddIn;

};

// Enter ourselves in this server's object map
OBJECT_ENTRY_AUTO(__uuidof(CoAddIn), CAddIn)

////////////////////////////////////////////////////////////////////////

/// ATL Trace Category for Sample CAI-specific messages
extern CTraceCategory atlTraceSampleCAI;

template <typename PARAM, typename CONTAINED>
HRESULT CreateInstanceWithParam(IUnknown *pOuterUnk,
                                PARAM param,
                                CComObject<CONTAINED> **ppObj)
{
  *ppObj = NULL;

  CComObject<CONTAINED> *pObj = new CComObject<CONTAINED>(pOuterUnk);
  pObj->SetVoid(pOuterUnk);
  pObj->SetParam(param);

  pObj->InternalFinalConstructAddRef();

  HRESULT hr = pObj->_AtlInitialConstruct();
  if (SUCCEEDED(hr)) hr = pObj->FinalConstruct();
  if (SUCCEEDED(hr)) hr = pObj->_AtlFinalConstruct();

  pObj->InternalFinalConstructRelease();

  if (FAILED(hr))
  {
    delete pObj;
    return hr;
  }

  *ppObj = pObj;

  return hr;
}

template <typename PARAM, typename CONTAINED>
HRESULT CreateInstanceWithParam(IUnknown *pOuterUnk,
                                PARAM param,
                                CComAggObject<CONTAINED> **ppObj)
{
  *ppObj = NULL;

  CComAggObject<CONTAINED> *pObj = new CComAggObject<CONTAINED>(pOuterUnk);
  pObj->SetVoid(pOuterUnk);
  pObj->m_contained.SetParam(param);

  pObj->InternalFinalConstructAddRef();

  HRESULT hr = pObj->_AtlInitialConstruct();
  if (SUCCEEDED(hr)) hr = pObj->FinalConstruct();
  if (SUCCEEDED(hr)) hr = pObj->_AtlFinalConstruct();

  pObj->InternalFinalConstructRelease();

  if (FAILED(hr))
  {
    delete pObj;
    return hr;
  }

  *ppObj = pObj;

  return hr;
}

template <class COCLASS,
          typename PARAM,
          class ITF>
HRESULT CreateInstanceWithParamItf(IUnknown *pOuterUnk,
                                   PARAM *param,
                                   ITF **ppItf,
                                   COCLASS **ppObj = NULL,
                                   const IID *piid = &_uuidof(ITF))
{
  *ppItf = NULL;

  COCLASS *pObjInternal;
  HRESULT hr = CreateInstanceWithParam(pOuterUnk, param, &pObjInternal);
  if (FAILED(hr)) return hr;

  hr = pObjInternal->QueryInterface(*piid, (void**)ppItf);
  if (FAILED(hr))
  {
    delete pObjInternal;
    return hr;
  }

  if (ppObj) *ppObj = pObjInternal;

  return hr;
}

class CSampleCAIModule : public CAtlDllModuleT< CSampleCAIModule >
{
public :
  DECLARE_LIBID(LIBID_SampleCAILib)
  DECLARE_REGISTRY_APPID_RESOURCEID(IDR_SAMPLECAI,
    "{5f4e04a0-1a92-11db-89d7-00508d75f9f1}")
  virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* pRegistrar) throw();

};

extern CSampleCAIModule _AtlModule;

const char * const DEF_HELLO_PHRASE = "Hello, world!";
const char * const SOFTWARE         = "SOFTWARE";
const char * const SAMPLES          = "Code Samples";
const char * const SAMPLECAI        = "Sample Common Add-In";
const char * const VAL_HELLO_PHRASE = "HelloPhrase";

const ULONG MAX_HELLO_PHRASE = 256UL;

std::string getHelloPhrase();

void setHelloPhrase(const std::string &strText);

// Local Variables:
// fill-column: 72
// indent-tabs-mode: nil
// show-trailing-whitespace: t
// End:

#endif // ADDIN_H_076A0C36_23B5_4BF6_B51B_DF624F49B364
